<template>
  <el-dialog
    :visible.sync="dialogFormVisible"
    v-if="dialogFormVisible"
    :modal="false"
    @close='handleCancle'
    :destroy-on-close="true"
    :close-on-click-modal="true"
    :before-close='outClose'
    top="0vh !important"
    width="100%"
    center
    :show-close="false">

    <!-- 自定义标题 -->
    <template slot="title">
      <div class="custom-dialog-header">
        <!-- 左侧信息区域 -->
        <div class="header-info">
          <!-- 标题区域 -->
          <div class="title-section">
            <span class="blue-block">▄▄▄</span>
            <span class="title-text">管道</span>
            <span class="red-block">▄▄▄</span>
            <span class="title-text">巡线轨迹</span>
          </div>

          <!-- 巡检员信息 -->
          <div class="inspector-section">
            <span class="icon-container">
              <i class="el-icon-user"></i>
            </span>
            <span class="inspector-name">{{ inspectorName }}</span>
          </div>

          <!-- 时间信息 -->
          <div class="time-info">
            <div class="time-group">
              <span class="time-label">任务开始时间</span>
              <span class="time-value">{{ taskStartTime }}</span>
            </div>

            <div class="time-group" v-if="state === 1">
              <span class="time-label">任务结束时间</span>
              <span class="time-value">{{ taskEndTime }}</span>
            </div>
          </div>

          <!-- 状态信息 -->
          <div class="status-section">
            <span class="status-indicator" :style="{ backgroundColor: statusColor }"></span>
            <span class="status-text">{{ statusText }}</span>
          </div>
        </div>

        <!-- 右侧按钮区域 -->
        <div class="button-section">

          <!-- 倍速控制按钮组 -->
          <div class="speed-control-group" v-if="isPlaying">
            <el-button
              size="mini"
              :type="playbackSpeed === 0.5 ? 'primary' : ''"
              @click="setPlaybackSpeed(0.5)"
              class="speed-btn">
              0.5x
            </el-button>
            <el-button
              size="mini"
              :type="playbackSpeed === 1 ? 'primary' : ''"
              @click="setPlaybackSpeed(1)"
              class="speed-btn">
              1x
            </el-button>
            <el-button
              size="mini"
              :type="playbackSpeed === 1.5 ? 'primary' : ''"
              @click="setPlaybackSpeed(1.5)"
              class="speed-btn">
              1.5x
            </el-button>
          </div>

          <!-- 开始回放按钮 -->
          <el-button
            v-if="!isPlaying"
            type="success"
            size="mini"
            @click="startPlayback"
            class="playback-btn">
            开始回放
          </el-button>

          <!-- 暂停按钮 -->
          <el-button
            v-if="isPlaying && !playbackPaused"
            type="warning"
            size="mini"
            @click="pausePlayback"
            class="playback-btn">
            暂停
          </el-button>

          <!-- 继续按钮 -->
          <el-button
            v-if="isPlaying && playbackPaused"
            type="success"
            size="mini"
            @click="resumePlayback"
            class="playback-btn">
            继续
          </el-button>

          <!-- 重置按钮 -->
          <el-button
            v-if="isPlaying"
            type="info"
            size="mini"
            @click="resetPlayback"
            class="reset-btn">
            重置
          </el-button>

          <el-button
            type="primary"
            size="mini"
            @click="handleCancle"
            class="close-btn">
            关闭页面
          </el-button>
        </div>
      </div>
    </template>

    <div>
      <div style="position: absolute;z-index: 10000;width: 100px;height: 200px;">
        <img :src=this.pictureSrc style="max-width: 100%;max-height: 100%;">
      </div>
      <baidu-map class="map" id="allmaps" :center="center" :zoom="zoom" style="height:825px" :scroll-wheel-zoom='true'>
      </baidu-map>
    </div>

  </el-dialog>
</template>

<script>
import {findTrail,findTrailNew} from "@/api/linepatrol/patrolRouteRecord/patrolRouteRecordManagement";
import {Mapa} from "../../../../utils/map.js";
import {getList, findLast} from "@/api/linepatrol/patrolStation/patrolStationManagement";

const mapvgl = require('mapvgl')

var sdata;
var ldata;
var localRoute;
let map;
var view;//MapVGL图层管理器
var points = [];//原始点信息数组
var bPoints = [];//百度化坐标数组。用于更新显示范围。
var makerPointsList = [];//用于更新动态轨迹的上传点位 变换图标

export default {
  name: 'PatrolRouteRecordManagementEdit.vue',
  components: {},
  data() {
    return {
      state: 0,
      beginTime: "",
      taskId: 0,
      timer: null,
      timerssa: null,
      list: null,
      listLoading: true,
      layout: "total, sizes, prev, pager, next, jumper",
      total: 0,
      selectRows: "",
      elementLoadingText: "正在加载...",
      dialogFormVisible: false,
      center: {
        /*lng: 116.403407,
        lat: 39.923761*/
      },
      queryForm: {
        pageNo: 1,
        pageSize: 100000,
      },
      zoom: 15,
      name: null,
      lineData: null,
      pictureSrc: '',

      // 新增动态数据字段
      inspectorName: '',
      taskStartTime: '',
      uploadTime: '',
      latestTime: '',
      taskEndTime: '',
      statusText: '',
      statusColor: '#379608',

      isPlaying: false, // 是否正在回放
      playbackPaused: false, // 回放是否暂停
      playbackIndex: 0, // 当前回放点索引
      playbackInterval: null, // 回放定时器
      playbackMarker: null, // 回放专用的覆盖物
      playbackLabel: null, // 回放专用的标签
      playbackSpeed: 1, // 回放速度（1表示正常速度）
      originalMarkerVisible: true, // 原始标记是否可见
    };
  },

  mounted() {
  },

  methods: {

    handleCancle() {
      console.log('%%%%%%%%%%%%%%', this.timerssa)
      clearTimeout(this.timerssa);  //清除延迟执行
      clearInterval(this.playbackInterval); // 清除回放定时器
      this.dialogFormVisible = false
      this.resetPlayback(); // 确保重置状态
    },

    outClose(done) {
      done()
      clearInterval(this.timer)
      this.resetPlayback(); // 确保重置状态
    },


    async show(val) {
      this.name = val.userName;
      this.state = val.state
      this.beginTime = val.createTime.match(/\d{4}-\d{1,2}-\d{1,2}/)[0];
      this.taskId = val.id

      // 更新头部数据
      this.inspectorName = val.userName || '巡检员';
      this.taskStartTime = this.formatTime(val.beginTime);
      this.uploadTime = this.formatTime(val.createTime);
      this.latestTime = this.formatTime(val.lastTime);
      this.taskEndTime = this.formatTime(val.endTime);

      // 更新状态显示
      if (this.state === 0) {
        this.statusText = '巡检中';
        this.statusColor = '#379608'; // 绿色
      } else {
        this.statusText = '已结束';
        this.statusColor = '#909399'; // 灰色
      }

      const {result} = await findTrail(this.taskId)
      sdata = result.trail;
      localRoute = result.localroute;
      this.dialogFormVisible = true;
      this.showint();
    },

    // 格式化时间方法
    formatTime(timeStr) {
      if (!timeStr) return '';
      // 将时间格式化为 YYYY-MM-DD HH:mm
      return timeStr.replace(/(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}):\d{2}/, '$1 $2');
    },

    showint() {
      Mapa("ES2HXlIFQmr5fEFgsXgyBVrK2gUvUsjF").then(BMapGL => {

        //数据准备,


        //地图操作开始
        map = new BMapGL.Map("allmaps", {minZoom: 2, maxZoom: 18});

        // 百度地图API功能
        // 初始化地图，设置中心点坐标和地图级别
        // 开启鼠标滚轮缩放
        map.enableScrollWheelZoom(true);


        // 2. 创建MapVGL图层管理器
        //赋值公共的
        view = new mapvgl.View({
          map: map
        });


        clearTimeout(this.timer);  //清除延迟执行
        this.timer = setTimeout(() => {   //设置延迟执行

          // this.shouye() //首页定位初始化

          this.showRoute(); //基础路线

          this.shouTrail(); //轨迹

          this.shouwStaio(); //点悬浮显示时间

          this.shouwStaioRen(); //显示人物

          this.getqz();
        }, 2000);


        // 当前任务状态为进行中时 开启定时任务  0 进行中 1 已结束
        if (this.state === 0) {
          // 定时动态生成新的轨迹点
          setTimeout(this.dynamicLine(), 5000);
        }


      })

    },

    shouye() {
      if (sdata.length !== 0) {
        //初始中心点
        var point = new BMapGL.Point(sdata[sdata.length - 1].lt, sdata[sdata.length - 1].ln);
        map.centerAndZoom(point, 15);
      }

    },


    //********************************基准路线******************************* */
    showRoute() {

      // 百度地图API功能

      //基准路径
      var polylineArr = [];
      var bglt;
      var bgln;
      for (var i = 1; i < localRoute.length; i++) {
        let newData = localRoute[1];
        for (let a = 0; a < newData.length; a++) {
          var lt = newData[a].lt;
          var ln = newData[a].ln;
          if (a == 0) {
            bglt = lt;
            bgln = ln;
          }
        }
      }
      for (let l = 1; l < localRoute.length; l++) {
        let po = [];
        let newData = localRoute[l];
        for (let b = 0; b < newData.length; b++) {
          let lt = newData[b].lt;
          let ln = newData[b].ln;
          po.push(new BMapGL.Point(lt, ln));
        }
        var polyline = new BMapGL.Polyline(po, {
          enableEditing: false,//是否启用线编辑，默认为false
          enableClicking: true,//是否响应点击事件，默认为true
          // icons: [icons],
          strokeWeight: '8',//折线的宽度，以像素为单位
          strokeOpacity: 0.8,//折线的透明度，取值范围0 - 1
          strokeColor: "blue" //折线颜色
        });
        polylineArr.push(polyline);
      }
      for (let l in polylineArr) {
        map.addOverlay(polylineArr[l]);//将覆盖物添加到地图中，一个覆盖物实例只能向地图中添加一次
      }
      var point = new BMapGL.Point(bglt, bgln);
      map.centerAndZoom(point, 15);

    },


    //********************************展示进页面前已经走过的轨迹******************************* */

    shouTrail() {
      var line = [];

      if (sdata.length > 0) {
        var geometrys = {
          geometry: {
            type: "LineString",
            coordinates: []
          }
        };

        for (var i = 0; i < sdata.length - 1; i++) {
          var lt = sdata[i].lt; // 经度
          var ln = sdata[i].ln; // 纬度
          var lists = [parseFloat(lt), parseFloat(ln)];
          geometrys.geometry.coordinates.push(lists);
        }
        line.push(geometrys);

        console.log('***', line);

        var views = new mapvgl.LineRainbowLayer({
          color: '#FF0000', // 颜色
          style: 'arrow',    // 关键：启用箭头样式
          width: 8,          // 增加线宽以使箭头更突出
          lineJoin: 'round',
          lineCap: 'round',
          data: line,
          opacity: 1
        });
        view.addLayer(views);


      }
    },


    //********************************轨迹点鼠标 悬浮显示弹窗******************************* */
    shouwStaio() {

      if (sdata.length > 0) {
        var datas = [];

        for (var i = 0; i < sdata.length; i++) {

          //轨迹线
          var lt = sdata[i].lt;//经度
          var ln = sdata[i].ln;//纬度
          var tm = sdata[i].tm;

          datas.push({
            geometry: {
              type: 'Point',
              coordinates: [lt, ln],
              time: tm
            }
          });

        }
        ;
        var pointlayer = new mapvgl.PointLayer({
          color: '#FF0000',
          size: 6,
          data: datas,
          enablePicked: true, // 是否可以拾取
          onMousemove: (e) => { // 点击事件
            // console.log('%%%%%%%%', e.dataItem.geometry.coordinates, e.dataItem.geometry.time);
            if (e.dataItem) {
              this.infoWindowObject = new BMapGL.InfoWindow(this.createWindowHtml(e.dataItem.geometry), {
                title: '',
                width: 260
              })
              let point = new BMapGL.Point(e.dataItem.geometry.coordinates[0], e.dataItem.geometry.coordinates[1]);
              map.openInfoWindow(this.infoWindowObject, point)
            }

          },
        });
        view.addLayer(pointlayer);

      }
    },

    createWindowHtml(item) {
      // 点击出窗口
      const html = `
        <div class="window-content">
            <div class="window-bottom">
              <span style="font-size: 16px;font-weight: bold;">路过时间：${this.beginTime + ' ' + item.time}</span>
            </div>

          </div>`
      return html
    },

    //********************************巡检员图标******************************* */

    shouwStaioRen() {


      if (sdata.length > 0) {
        var pointTwinkle1 = new BMapGL.Point(sdata[sdata.length - 1].lt, sdata[sdata.length - 1].ln);

        if (this.state === 0) {

          var pictureSrcss1 = require('@/assets/images/xjy02.gif');
          let showShan1 = '<img style="width: 120px; height: 120px; transform: rotateY(180deg);" src="' + pictureSrcss1 + '" />';
          const option1 = {
            position: pointTwinkle1,
            offset: new BMapGL.Size(-52, -105),  //X  y
          };
          const Label1 = new BMapGL.Label(showShan1, option1);
          Label1.setStyle({
            border: '50%',
            backgroundColor: 'RGBA(0,0,0,0)',
            width: '120px',
            height: '120px',
          });
          map.addOverlay(Label1);

          makerPointsList.push(Label1)
        } else {

          //任务结束时显示的巡检人员
          var pictureSrcss = require('@/assets/images/xjy.png');
          let showShan = '<img style="width: 80px; height: 95px;" src="' + pictureSrcss + '" />';
          const option = {
            position: pointTwinkle1,
            offset: new BMapGL.Size(-40, -100),
          };
          const Label = new BMapGL.Label(showShan, option);
          Label.setStyle({
            border: '50%',
            backgroundColor: 'RGBA(0,0,0,0)',
            width: '95px',
            height: '100px',
          });
          map.addOverlay(Label);
          makerPointsList.push(Label)
        }


        const option1 = {
          position: pointTwinkle1,
          offset: new BMapGL.Size(-30, -124),
        };
        const Label1 = new BMapGL.Label(this.name, option1);
        Label1.setStyle({
          color: "black",           // 文字颜色改为黑色
          backgroundColor: "white", // 背景改为白色
          border: "1px solid red",  // 边框改为1像素红色实线
          // 可选：调整其他样式（如字体、内边距等）
          fontSize: "14px",         // 字体大小
          padding: "3px",           // 内边距
          borderRadius: "3px",      // 圆角（可选）
        });
        map.addOverlay(Label1);

        makerPointsList.push(Label1)

      }
    },

    //********************************起始点标签******************************* */


    getqz() {
      // 添加起点和终点标签
      if (sdata.length > 0) {
        // 起点标签 - 已修正箭头样式
        var startPoint = new BMapGL.Point(sdata[0].lt, sdata[0].ln);
        let startLabel = `
<div style="background: #52c41a; padding: 6px 9px; border-radius: 4px; color: white; font-weight: bold; font-size: 15px; position: relative; display: inline-block; white-space: nowrap; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
  <div style="display: flex; align-items: center; gap: 8px;">
    <span style="font-size: 15px;">起点</span>
    <span style="font-size: 15px;">${sdata[0].tm}</span>
  </div>
  <!-- 修改后的箭头：方向反转，线更粗更长，箭头更大 -->
  <div style="position: absolute; top: 90%; left: -28px; transform: translateY(-50%) rotate(135deg);">
    <div style="display: flex; align-items: center;">
      <div style="width: 25px; height: 5px; background: #52c41a;"></div>
      <div style="width: 0; height: 0; border-left: 10px solid #52c41a; border-top: 7px solid transparent; border-bottom: 5px solid transparent;"></div>
    </div>
  </div>
</div>
`;

        // 使用自定义覆盖物替代Label
        const StartLabelOverlay = function (point, html) {
          this._point = point;
          this._html = html;
        }
        StartLabelOverlay.prototype = new BMapGL.Overlay();
        StartLabelOverlay.prototype.initialize = function (map) {
          this._map = map;
          const div = document.createElement('div');
          div.innerHTML = this._html;
          div.style.position = 'absolute';
          div.style.zIndex = '100';
          div.style.pointerEvents = 'none';
          map.getPanes().labelPane.appendChild(div);
          this._div = div;
          return div;
        }
        StartLabelOverlay.prototype.draw = function () {
          const pixel = this._map.pointToOverlayPixel(this._point);
          this._div.style.left = (pixel.x + 24) + 'px';
          this._div.style.top = (pixel.y - this._div.offsetHeight / 2 - 20) + 'px';
        }

        const startOverlay = new StartLabelOverlay(startPoint, startLabel);
        map.addOverlay(startOverlay);

        // 终点标签 - 同步修改箭头样式
        var endPoint = new BMapGL.Point(sdata[sdata.length - 1].lt, sdata[sdata.length - 1].ln);
        let endLabel = `
<div style="background: #f5222d; padding: 6px 9px; border-radius: 4px; color: white; font-weight: bold; font-size: 15px; position: relative; display: inline-block; white-space: nowrap; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
  <div style="display: flex; align-items: center; gap: 8px;">
    <span style="font-size: 15px;">终点</span>
    <span style="font-size: 15px;">${sdata[sdata.length - 1].tm}</span>
  </div>
  <!-- 修改后的箭头：方向反转，线更粗更长，箭头更大 -->
  <div style="position: absolute; top: 90%; left: -28px; transform: translateY(-50%) rotate(135deg);">
    <div style="display: flex; align-items: center;">
      <div style="width: 25px; height: 5px; background: #f5222d;"></div>
      <div style="width: 0; height: 0; border-left: 10px solid #f5222d; border-top: 7px solid transparent; border-bottom: 7px solid transparent;"></div>
    </div>
  </div>
</div>
`;

        const EndLabelOverlay = function (point, html) {
          this._point = point;
          this._html = html;
        }
        EndLabelOverlay.prototype = new BMapGL.Overlay();
        EndLabelOverlay.prototype.initialize = function (map) {
          this._map = map;
          const div = document.createElement('div');
          div.innerHTML = this._html;
          div.style.position = 'absolute';
          div.style.zIndex = '100';
          div.style.pointerEvents = 'none';
          map.getPanes().labelPane.appendChild(div);
          this._div = div;
          return div;
        }
        EndLabelOverlay.prototype.draw = function () {
          const pixel = this._map.pointToOverlayPixel(this._point);
          this._div.style.left = (pixel.x + 24) + 'px';
          this._div.style.top = (pixel.y - this._div.offsetHeight / 2 - 20) + 'px';
        }

        const endOverlay = new EndLabelOverlay(endPoint, endLabel);
        if (this.state === 1) {
          map.addOverlay(endOverlay);
        }

        // 添加地图事件监听，确保缩放和移动时箭头位置更新
        map.addEventListener('zoomend', function () {
          startOverlay.draw();
          if (this.state === 1) {

            endOverlay.draw();
          }
        });
        map.addEventListener('moveend', function () {
          startOverlay.draw();
          if (this.state === 1) {
            endOverlay.draw();
          }
        });
      }
    },

//-------------------------------------------------------------------------------------
    //新的点，加入到轨迹中。
    async dynamicLine() {

      var makerPoints = [];
      var newLinePoints = [];
      var len;

      const {result} = await findTrailNew(this.taskId)
      var sdataNew = result.trail;

      //新轨迹去重
      // console.log('%%%%%', sdataNew)

      // 使用Map存储最新tm记录
      const tmMap = new Map();
      sdataNew.forEach(item => {
        const ln = item.ln;
        const tm = item.tm;

        if (!tmMap.has(ln) || tm > tmMap.get(ln).tm) {
          tmMap.set(ln, item);
        }
      });

      sdataNew = null;
      // 从Map中提取值，得到结果数组
      sdataNew = Array.from(tmMap.values());

      sdataNew.sort((a, b) => {
        const timeA = new Date('1970/01/01 ' + a.tm);
        const timeB = new Date('1970/01/01 ' + b.tm);

        return timeA - timeB;
      });
      // console.log('$$$$$$$$$$$$$$$', sdataNew);


      // 添加最新的巡检点
      var point = {
        "lng": sdataNew[sdataNew.length - 1].lt,
        "lat": sdataNew[sdataNew.length - 1].ln,
        "lo": sdataNew[sdataNew.length - 1].lo,
        "tm": sdataNew[sdataNew.length - 1].tm,
        "status": sdataNew.length - 1,
        "lt": sdataNew[sdataNew.length - 1].lt,  // 添加经度 用户经记录人员角度
        "ln": sdataNew[sdataNew.length - 1].ln   // 添加纬度
      }

      //最新的轨迹点
      makerPoints.push(point);
      this.addMarker(makerPoints);//增加对应该的轨迹点


      //轨迹连线
      if (sdataNew.length > 0) {


        for (var i = 0; i < sdataNew.length; i++) {
          var lt = sdataNew[i].lt;//经度
          var ln = sdataNew[i].ln;//纬度
          var tm = sdataNew[i].tm;
          var point = {"lng": lt, "lat": ln, "status": 1}
          points.push(point);
          bPoints.push(new BMapGL.Point(lt, ln));
        }
      }

      len = points.length;
      newLinePoints = points.slice(len - 2, len);//最后两个点用来画线。
      this.addLine(newLinePoints);//增加轨迹线

      this.addLine(points.slice(len - 3, len - 1));//增加轨迹线


      //自动定位到最新位置
      // var point = new BMapGL.Point(bglt, bgln);
      // map.centerAndZoom(point, 17);

      if (this.state === 0) {
        this.timerssa = setTimeout(this.dynamicLine, 5000);
      } else {
        clearTimeout(this.timerssa);  //清除延迟执行
      }
    },

    //-----------------------------------添加线
    addLine(pointsline) {

      var linePoints = [],
        pointsLen = pointsline.length, i, polyline;
      if (pointsLen == 0) {
        return;
      }

      // 创建标注对象并添加到地图
      for (i = 0; i < pointsLen; i++) {
        linePoints.push(new BMapGL.Point(pointsline[i].lng, pointsline[i].lat));
      }

      polyline = new BMapGL.Polyline(linePoints, {
        sequence: true,
        strokeTexture: { // width/height 需要是2的n次方
          url: require('@/assets/images/yellow05.png'),
          width: 20,	// 图片的宽度F
          height: 64	// 图片的高度
        },
        strokeWeight: 8,
        strokeOpacity: 1
      });   //创建折线
      map.addOverlay(polyline);   //增加折线
    },

    // 获取随机数
    getRandom(n) {
      return Math.floor(Math.random() * n + 1)
    },

    //根据点信息实时更新地图显示范围，让轨迹完整显示。设置新的中心点和显示级别
    setZoom(bPoints) {
      var view = map.getViewport(eval(bPoints));
      var mapZoom = view.zoom;
      var centerPoint = view.center;
      map.centerAndZoom(centerPoint, mapZoom);
    },

    // 在轨迹点上创建图标，并添加点击事件，显示轨迹点信息。points,数组。
// 在轨迹点上创建图标，并添加点击事件，显示轨迹点信息。points,数组。
    addMarker(pointsna) {
      // 添加点位
      var pointsLen = pointsna.length;
      if (pointsLen == 0) {
        return;
      }

      // 计算移动方向角度（相对于正北方向）
      function calculateDirection(currentIndex, pointsArray) {
        if (currentIndex <= 0 || currentIndex >= pointsArray.length - 1) {
          return 0;
        }

        const prevPoint = pointsArray[currentIndex - 1];
        const nextPoint = pointsArray[currentIndex + 1];

        // 计算经度差和纬度差
        const deltaLng = nextPoint.lt - prevPoint.lt;
        const deltaLat = nextPoint.ln - prevPoint.ln;

        // 计算角度（弧度转角度）- 修正后的计算
        let angle = Math.atan2(deltaLng, deltaLat) * 180 / Math.PI;

        // 调整角度，使0度指向正北
        angle = (360 - angle) % 360;

        return angle;
      }

      // 判断是否需要旋转180度（往北或往西时）
      function shouldRotate180(angle) {

        // 正北方向：337.5°–22.5°
        const isNorth = (angle >= 337.5 || angle < 22.5);
        // 正西方向：247.5°–292.5°
        const isWest = (angle >= 67.5 && angle < 112.5);
        // 正东方向：67.5°–112.5°
        const isEast = (angle >= 247.5 && angle < 292.5);
        // 正南方向：157.5°–202.5°
        const isSouth = (angle >= 157.5 && angle < 202.5);

        // 新增四个斜方向
        // 东北方向：22.5°–67.5°
        const isNortheast = (angle >= 22.5 && angle < 67.5);
        // 东南方向：112.5°–157.5°
        const isSoutheast = (angle >= 112.5 && angle < 157.5);
        // 西南方向：202.5°–247.5°
        const isSouthwest = (angle >= 202.5 && angle < 247.5);
        // 西北方向：292.5°–337.5°
        const isNorthwest = (angle >= 292.5 && angle < 337.5);

        // 显式返回逻辑：北/西/西南/西北为true，南/东/东北/东南为false
        if (isNorth || isWest || isSouthwest || isNorthwest) {
          return true;
        } else if (isEast || isSouth || isNortheast || isSoutheast) {
          return false;
        } else {
          return false;
        }
      }

      var carIcon = new BMapGL.Icon(
        require("@/assets/images/23.png"),
        new BMapGL.Size(10, 10),
        {
          imageSize: new BMapGL.Size(10, 10),
          imageOffset: new BMapGL.Size(0, 0)
        }
      );

      for (var i = 0; i < pointsLen; i++) {
        var lo = pointsna[i].lo;
        var tm = pointsna[i].tm;
        var point = new BMapGL.Point(pointsna[i].lng, pointsna[i].lat);
        var marker = new BMapGL.Marker(point, {icon: carIcon});

        map.addOverlay(marker);

        getpdetail(marker);

        function getpdetail(marker) {
          var opts = {
            width: 260,     // 信息窗口宽度
            title: "", // 信息窗口标题
            message: ""
          };
          const content = `
    <div class="window-content">
        <div class="window-bottom">
          <span style="font-size: 16px;font-weight: bold;">路过时间：${tm}</span>
        </div>
      </div>`

          var infoWindow = new BMapGL.InfoWindow(content, opts);  // 创建信息窗口对象
          marker.addEventListener("mouseover", function () {
            this.openInfoWindow(infoWindow);
          });
        }
      }

      // 创建标注 - 这里添加方向判断逻辑
      for (var i = 0; i < pointsLen; i++) {
        if (makerPointsList.length !== 0) {
          var pointTwinkle = new BMapGL.Point(pointsna[i].lng, pointsna[i].lat);
          var time = pointsna[i].tm;

          // 计算方向角度
          let directionAngle = 0;
          let shouldRotate = false;

          // 只有存在前一个点和后一个点时才能计算方向
          if (i > 0 && i < pointsna.length - 1) {
            directionAngle = this.calculateDirection(i, pointsna);
            shouldRotate = this.shouldRotate180(directionAngle);
          }

          if (this.state === 0) {
            // 把label的图标隐藏
            for (var m = 0; m < makerPointsList.length; m++) {
              var Labelmodel = makerPointsList[m];
              Labelmodel.setStyle({
                display: "none"
              });
            }

            var pictureSrcss = require('@/assets/images/xjy02.gif');

            // 根据方向判断是否翻转图标
            const rotationStyle = shouldRotate ? 'transform: rotateY(180deg);' : '';
            let showShan = `<img style="width: 120px; height: 120px; ${rotationStyle}" src="${pictureSrcss}" />`;

            const option = {
              position: pointTwinkle,
              offset: new BMapGL.Size(-52, -105),  //X  y
            };
            const Label = new BMapGL.Label(showShan, option);
            Label.setStyle({
              border: '50%',
              backgroundColor: 'RGBA(0,0,0,0)',
              width: '120px',
              height: '120px',
            });

            map.addOverlay(Label);
            makerPointsList.push(Label);

          } else {
            // 任务结束时显示的巡检人员 - 不需要方向判断
            var pictureSrcss = require('@/assets/images/xjy.png');
            let showShan = `<img style="width: 80px; height: 95px;" src="${pictureSrcss}" />`;
            const option = {
              position: pointTwinkle,
              offset: new BMapGL.Size(-40, -100),
            };
            const Label = new BMapGL.Label(showShan, option);
            Label.setStyle({
              border: '50%',
              backgroundColor: 'RGBA(0,0,0,0)',
              width: '80px',
              height: '130px',
            });

            map.addOverlay(Label);
            makerPointsList.push(Label);
          }

          // 显示人员顶部的名称
          const option1 = {
            position: pointTwinkle,
            offset: new BMapGL.Size(-30, -124),
          };
          const Label1 = new BMapGL.Label(this.name + time, option1);
          Label1.setStyle({
            color: "black",
            backgroundColor: "white",
            border: "1px solid red",
            fontSize: "14px",
            padding: "3px",
            borderRadius: "3px",
          });

          map.addOverlay(Label1);
          makerPointsList.push(Label1);
        }
      }
    },

    // ----------------------------------轨迹回放-----------------------------------------

    // 计算两点之间的距离（米）
    calculateDistance(lat1, lng1, lat2, lng2) {
      const R = 6371000; // 地球半径（米）
      const dLat = (lat2 - lat1) * Math.PI / 180;
      const dLng = (lng2 - lng1) * Math.PI / 180;
      const a =
        Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
        Math.sin(dLng / 2) * Math.sin(dLng / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      return R * c;
    },

    // 计算时间差（秒）
    calculateTimeDifference(time1, time2) {
      const [h1, m1, s1] = time1.split(':').map(Number);
      const [h2, m2, s2] = time2.split(':').map(Number);
      return (h2 - h1) * 3600 + (m2 - m1) * 60 + (s2 - s1);
    },

// 计算移动方向角度（相对于正北方向）
    calculateDirection(currentIndex) {
      if (currentIndex <= 0 || currentIndex >= sdata.length - 1) {
        return 0;
      }

      const prevPoint = sdata[currentIndex - 1];
      const nextPoint = sdata[currentIndex + 1];

      // 计算经度差和纬度差
      const deltaLng = nextPoint.lt - prevPoint.lt;
      const deltaLat = nextPoint.ln - prevPoint.ln;

      // 计算角度（弧度转角度）- 修正后的计算
      let angle = Math.atan2(deltaLng, deltaLat) * 180 / Math.PI;

      // 调整角度，使0度指向正北
      angle = (360 - angle) % 360;

      return angle;
    },

// 判断是否需要旋转180度（往北或往西时）
    shouldRotate180(angle) {
      // console.log('%%%%%%%%%%', angle);
      // 正北方向：337.5°–22.5°
      const isNorth = (angle >= 337.5 || angle < 22.5);
      // 正西方向：247.5°–292.5°
      const isWest = (angle >= 67.5 && angle < 112.5);
      // 正东方向：67.5°–112.5°
      const isEast = (angle >= 247.5 && angle < 292.5);
      // 正南方向：157.5°–202.5°
      const isSouth = (angle >= 157.5 && angle < 202.5);

      // 新增四个斜方向
      // 东北方向：22.5°–67.5°
      const isNortheast = (angle >= 22.5 && angle < 67.5);
      // 东南方向：112.5°–157.5°
      const isSoutheast = (angle >= 112.5 && angle < 157.5);
      // 西南方向：202.5°–247.5°
      const isSouthwest = (angle >= 202.5 && angle < 247.5);
      // 西北方向：292.5°–337.5°
      const isNorthwest = (angle >= 292.5 && angle < 337.5);

      // console.log('方向判断:', '北:', isNorth, '西:', isWest, '东:', isEast, '南:', isSouth,
      //   '东北:', isNortheast, '东南:', isSoutheast, '西南:', isSouthwest, '西北:', isNorthwest);

      // 显式返回逻辑：北/西/西南/西北为true，南/东/东北/东南为false
      if (isNorth || isWest || isSouthwest || isNorthwest) {
        return true;
      } else if (isEast || isSouth || isNortheast || isSoutheast) {
        return false;
      } else {
        // 理论上应该覆盖所有角度，但为安全起见保留默认返回
        return false;
      }
    },

    // 设置回放速度
    setPlaybackSpeed(speed) {
      this.playbackSpeed = speed;

      // 如果正在播放且没有暂停，需要重新设置定时器
      if (this.isPlaying && !this.playbackPaused) {
        clearInterval(this.playbackInterval);
        this.animatePlayback();
      }
    },

    // 开始轨迹回放
    startPlayback() {
      if (sdata.length === 0) return;

      // 创建回放专用的覆盖物
      this.createPlaybackMarker();

      this.isPlaying = true;
      this.playbackPaused = false;
      this.playbackIndex = 0;
      this.playbackSpeed = 1; // 默认1倍速

      // 开始动画
      this.animatePlayback();
    },

    // 暂停回放
    pausePlayback() {
      this.playbackPaused = true;
      clearInterval(this.playbackInterval);
    },

    // 继续回放
    resumePlayback() {
      this.playbackPaused = false;
      this.animatePlayback();
    },

    // 重置回放
    resetPlayback() {
      // 清除定时器
      clearInterval(this.playbackInterval);

      // 重置状态变量
      this.isPlaying = false;
      this.playbackPaused = false;
      this.playbackIndex = 0;
      this.playbackSpeed = 1;

      // 移除回放覆盖物
      if (this.playbackMarker) {
        map.removeOverlay(this.playbackMarker);
        this.playbackMarker = null;
      }
      if (this.playbackLabel) {
        map.removeOverlay(this.playbackLabel);
        this.playbackLabel = null;
      }
    },

    createPlaybackMarker() {
      // 移除旧的覆盖物
      if (this.playbackMarker) {
        map.removeOverlay(this.playbackMarker);
      }
      if (this.playbackLabel) {
        map.removeOverlay(this.playbackLabel);
      }

      // 创建新的覆盖物
      const point = new BMapGL.Point(sdata[0].lt, sdata[0].ln);
      const pictureSrcss = require('@/assets/images/xjy02.gif');

      // 初始不旋转
      const iconContent = `<img style="width: 120px; height: 120px;" src="${pictureSrcss}" />`;

      // 巡检员图标
      this.playbackMarker = new BMapGL.Label(iconContent, {
        position: point,
        offset: new BMapGL.Size(-52, -105)
      });
      this.playbackMarker.setStyle({
        border: '50%',
        backgroundColor: 'RGBA(0,0,0,0)',
        width: '120px',
        height: '120px',
      });

      // 巡检员名字标签
      const timeStr = sdata[0].tm.substring(0, 5);
      const labelContent = `
        <div style="display: flex; flex-direction: column; align-items: center;">
          <div>${this.name}</div>
        </div>
      `;

      this.playbackLabel = new BMapGL.Label(labelContent, {
        position: point,
        offset: new BMapGL.Size(-30, -124)
      });
      this.playbackLabel.setStyle({
        color: "black",
        backgroundColor: "white",
        border: "1px solid red",
        fontSize: "14px",
        padding: "3px",
        borderRadius: "3px",
        textAlign: "center",
      });

      map.addOverlay(this.playbackMarker);
      map.addOverlay(this.playbackLabel);
    },

    // 执行轨迹回放动画
    animatePlayback() {
      clearInterval(this.playbackInterval);

      // 根据速度计算间隔时间
      const baseInterval = 100; // 1倍速基准间隔（毫秒）
      const interval = baseInterval / this.playbackSpeed;

      this.playbackInterval = setInterval(() => {
        if (this.playbackPaused) return;

        if (this.playbackIndex >= sdata.length) {
          // 回放结束
          clearInterval(this.playbackInterval);
          this.isPlaying = false;
          this.changePlaybackMarkerToStatic();
          return;
        }

        const point = new BMapGL.Point(
          sdata[this.playbackIndex].lt,
          sdata[this.playbackIndex].ln
        );

        // 计算当前时速
        let speed = 0;
        if (this.playbackIndex > 0) {
          const prevPoint = sdata[this.playbackIndex - 1];
          const distance = this.calculateDistance(
            prevPoint.ln, prevPoint.lt,
            sdata[this.playbackIndex].ln, sdata[this.playbackIndex].lt
          );

          const timeDiff = this.calculateTimeDifference(
            prevPoint.tm,
            sdata[this.playbackIndex].tm
          );

          if (timeDiff > 0) {
            speed = Math.round((distance / timeDiff) * 3.6);
          }
        }

        // 计算移动方向
        const directionAngle = this.calculateDirection(this.playbackIndex);
        const shouldRotate = this.shouldRotate180(directionAngle);

        // 更新覆盖物位置和方向
        this.updatePlaybackMarker(point, shouldRotate, speed, this.playbackIndex);

        this.playbackIndex++;
      }, interval);
    },

    // 更新回放标记的方向
    updatePlaybackMarker(point, shouldRotate, speed, index) {
      this.playbackMarker.setPosition(point);
      this.playbackLabel.setPosition(point);

      const timeStr = sdata[index].tm.substring(0, 5);

      // console.log("~~~",shouldRotate)
      // 根据方向设置图标旋转
      const rotationStyle = !shouldRotate ? 'transform: rotateY(180deg);' : '';
      const pictureSrcss = require('@/assets/images/xjy02.gif');

      const iconContent = `<img style="width: 120px; height: 120px; ${rotationStyle}" src="${pictureSrcss}" />`;
      this.playbackMarker.setContent(iconContent);

      // 更新标签内容
      const labelContent = `
        <div style="display: flex; flex-direction: column; align-items: center;">
          <div>${this.name} ${timeStr} <span style="font-size: 13px; color: #f5222d; font-weight: bold;">${speed} km/h</span></div>
        </div>
      `;
      this.playbackLabel.setContent(labelContent);

      // 平滑移动地图中心点
      // map.panTo(point);
    },

    changePlaybackMarkerToStatic() {
      if (!this.playbackMarker) return;
      const pictureSrcss = require('@/assets/images/xjy.png');
      const showShan = `<img style="width: 80px; height: 95px;" src="${pictureSrcss}" />`;

      // 判断任务是否进行中
      if (this.state === 0) {
        this.playbackMarker.setContent("");
        this.playbackLabel.setContent("");
        return;
      } else {
        this.playbackMarker.setContent(showShan);
      }


      this.playbackMarker.setOffset(new BMapGL.Size(-40, -100));

      // 更新标签为最终时间
      const lastPoint = sdata[sdata.length - 1];
      const timeStr = lastPoint.tm.substring(0, 5); // 只显示时分，去掉秒
      const labelContent = `
        <div style="display: flex; flex-direction: column; align-items: center;">
          <div>${this.name}</div>
        </div>
      `;
      this.playbackLabel.setContent(labelContent);
    },
  }
}
</script>

<style lang="scss" scoped>
.custom-dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 10px 15px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #ebeef5;
}

.header-info {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 15px;
  margin-left: 30px;
}

.title-section {
  display: flex;
  align-items: center;
  margin-right: 15px;

  .blue-block {
    color: #3131FF;
    padding-bottom: 10px;
    margin-right: 5px;
  }

  .red-block {
    color: #FF0000;
    padding-bottom: 10px;
    margin: 0 5px;
    margin-left: 10px;
  }

  .title-text {
    font-weight: bold;
    font-size: 16px;
  }
}

.inspector-section {
  display: flex;
  align-items: center;
  background-color: #ecf5ff;
  padding: 4px 10px;
  border-radius: 4px;

  .icon-container {
    margin-right: 5px;
    color: #409EFF;
  }

  .inspector-name {
    font-weight: bold;
  }
}

.time-info {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;

  .time-group {
    display: flex;
    flex-direction: column;

    .time-label {
      font-size: 15px;
      color: #222;
      margin-bottom: 5px;
    }

    .time-value {
      font-size: 16px;
      font-weight: 600;
      color: #111;
    }
  }
}

.status-section {
  display: flex;
  align-items: center;
  background-color: #f0f9eb;
  padding: 4px 10px;
  border-radius: 4px;

  .status-indicator {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #379608;
    margin-right: 5px;
  }

  .status-text {
    color: #379608;
    font-weight: bold;
  }
}

.button-section {
  flex-shrink: 0;
  display: flex;
  gap: 10px;
}

.close-btn {
  background-color: #409EFF;
  border-color: #409EFF;
  color: white;
  font-size: 16px !important;
  font-weight: bold;
  padding: 7px 15px;
  border-radius: 4px;

  &:hover {
    background-color: #66b1ff;
    border-color: #66b1ff;
  }
}

/* 调整对话框头部样式 */
:deep(.el-dialog__header) {
  padding: 0;
}

:deep(.el-dialog__headerbtn) {
  display: none; /* 完全隐藏默认关闭按钮 */
}

/* 在原有样式基础上添加 */
.playback-btn {
  margin-left: 10px;
  background-color: #52c41a;
  border-color: #52c41a;
  color: white;
  font-weight: bold;
  font-size: 16px !important;
  padding: 7px 15px;
  border-radius: 4px;

  &:hover {
    background-color: #73d13d;
    border-color: #73d13d;
  }
}

.reset-btn {
  background-color: #909399;
  border-color: #909399;
  color: white;
  font-weight: bold;
  font-size: 16px !important;
  padding: 7px 15px;
  border-radius: 4px;

  &:hover {
    background-color: #a6a9ad;
    border-color: #a6a9ad;
  }
}

.speed-control-group {
  display: flex;
  gap: 5px;
  margin-right: 10px;
}
</style>
